home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- ** **
- ** Module: SR_MacDialog.c **
- ** **
- ** **
- ** Purpose: Modal dialog routines **
- ** **
- ** **
- ** **
- ** Copyright (C) 1996-1997 Apple Computer, Inc. All rights reserved. **
- ** **
- ** **
- *****************************************************************************/
- #include "QD3D.h"
- #include "QD3DExtension.h"
-
- #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
-
- #define BUILDING_FOR_SYSTEM7 1
-
- #include <assert.h>
- #include <Dialogs.h>
- #include <Sound.h>
- #include <string.h>
- #include <Devices.h>
- #include <ToolUtils.h>
- #include <Aliases.h>
- #include <Resources.h>
- #include <TextUtils.h>
-
- #include "SR.h"
- #include "SR_MacDialog.h"
-
-
- /******************************************************************************
- ** **
- ** Dialog ID's **
- ** **
- *****************************************************************************/
-
- #define SR_DLOG_ID 128
- #define SR_MOVABLE_DLOG_ID 129
- #define SR_DLOG_OK 1
- #define SR_DLOG_CANCEL 2
- #define SR_DLOG_CHECKBOX 3
-
-
- /******************************************************************************
- ** **
- ** Forward Declarations **
- ** **
- *****************************************************************************/
-
- static TQ3Status SR_ModalDialog(
- TQ3RendererObject renderer,
- TQ3Boolean *canceled,
- void *rendererPrivate);
-
- static TQ3Status SR_MovableModalDialog(
- TQ3RendererObject renderer,
- TQ3DialogAnchor dialogAnchor,
- TQ3Boolean *canceled,
- void *rendererPrivate);
-
- static DialogPtr SR_LoadDialog(
- short dlogId,
- void *rendererPrivate);
-
- static TQ3Status HandleHit(
- DialogPtr dialog,
- short itemHit,
- TQ3Boolean *done,
- TQ3RendererObject renderer,
- TQ3Boolean *canceled,
- void *rendererPrivate);
-
- static TQ3Boolean HandledEvent(
- EventRecord *event,
- DialogPtr dialog,
- short *itemHit,
- TQ3Boolean *done,
- TQ3RendererObject renderer,
- TQ3Boolean *canceled,
- void *rendererPrivate);
-
- static void HandleMenuClick(
- long menuItem);
-
- static void DrawDefaultButtonOutline(
- DialogPtr dialog,
- short item);
-
- Boolean ModalDialogFilter(
- DialogPtr dialog,
- EventRecord *event,
- short *itemHit);
-
- void SimulateButtonClick(
- DialogPtr dialog,
- short item);
-
-
- /******************************************************************************
- ** **
- ** Globals **
- ** **
- *****************************************************************************/
-
- static ModalFilterUPP SRgModalFilterUPP = NULL;
-
- /*
- * The next two statics are needed to set and reset the Resource chain prior to
- * calling out to the applications Event handler
- */
- static short SRgOldResFile,
- SRgResFile;
-
- extern AliasHandle SRgAliasHandle;
-
-
- /******************************************************************************
- ** **
- ** Naming Routines **
- ** **
- *****************************************************************************/
-
- /*===========================================================================*\
- *
- * Routine: SR_GetNameString()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status SR_GetNameString(
- unsigned char *dataBuffer,
- unsigned long bufferSize,
- unsigned long *actualDataSize)
- {
- TQ3Status status = kQ3Success;
- Boolean wasChanged;
- FSSpec fileSpec;
- OSErr macErr;
- Str255 tempBuffer;
-
- /*
- * Get at the resource file for this renderer and open the resource
- * file, locate the renderer name string and close the res file
- * returning the string in the buffer we were passed.
- */
- SRgOldResFile = CurResFile();
-
- macErr = ResolveAlias(NULL, SRgAliasHandle, &fileSpec, &wasChanged);
-
- if (macErr == noErr) {
- SRgResFile = FSpOpenResFile(&fileSpec, fsRdPerm);
-
- if (SRgResFile != -1) {
- *actualDataSize = 0L;
- GetIndString(tempBuffer, SR_NAME_RESOURCE, 1);
-
- /* trim the buffer if necessary */
- *actualDataSize = (tempBuffer[0] > bufferSize) ?
- bufferSize : tempBuffer[0];
-
- if (dataBuffer != NULL) {
- /* copy from the pascal str returned by the res mgr */
- memcpy(
- (char *)dataBuffer,
- (char *) &tempBuffer[1],
- *actualDataSize );
-
- /* and terminate the string */
- dataBuffer[*actualDataSize] = '\0';
- }
-
- CloseResFile(SRgResFile);
- UseResFile(SRgOldResFile);
- } else {
- Q3XMacintoshError_Post(ResError());
- status = kQ3Failure;
- }
- } else {
- Q3XMacintoshError_Post(macErr);
- status = kQ3Failure;
- }
-
- if (status == kQ3Failure || ResError()) {
- *actualDataSize = 0L;
- dataBuffer = NULL;
- }
-
-
- return (status);
- }
-
-
- /******************************************************************************
- ** **
- ** Dialog Routines **
- ** **
- *****************************************************************************/
-
- /*===========================================================================*\
- *
- * Routine: SR_MacModalDialog()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status SR_MacModalDialog(
- TQ3RendererObject renderer,
- TQ3DialogAnchor dialogAnchor,
- TQ3Boolean *canceled,
- void *rendererPrivate)
- {
- TQ3Status status;
- Boolean wasChanged;
- FSSpec fileSpec;
- OSErr macErr;
-
- SRgOldResFile = CurResFile();
-
- macErr = ResolveAlias(NULL, SRgAliasHandle, &fileSpec, &wasChanged);
-
- if (macErr == noErr) {
- SRgResFile = FSpOpenResFile(&fileSpec, fsRdPerm);
-
- if (SRgResFile != -1) {
- if (dialogAnchor.clientEventHandler == NULL) {
- status = SR_ModalDialog(renderer, canceled, rendererPrivate);
- } else {
- status = SR_MovableModalDialog(
- renderer,
- dialogAnchor,
- canceled,
- rendererPrivate);
- }
- CloseResFile(SRgResFile);
- UseResFile(SRgOldResFile);
- } else {
- Q3XMacintoshError_Post(ResError());
- return (kQ3Failure);
- }
- } else {
- Q3XMacintoshError_Post(macErr);
- status = kQ3Failure;
- }
-
- return (status);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: SR_MacModalDialog()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status SR_ModalDialog(
- TQ3RendererObject renderer,
- TQ3Boolean *canceled,
- void *rendererPrivate)
- {
- DialogPtr dialog;
- short itemHit;
- TQ3Boolean done = kQ3False;
- TQ3Status status = kQ3Success;
-
- if (SRgModalFilterUPP == NULL) {
- SRgModalFilterUPP = NewModalFilterProc(ModalDialogFilter);
- }
-
- if (SRgModalFilterUPP == NULL) {
- Q3XMacintoshError_Post(MemError());
- return (kQ3Failure);
- }
-
- dialog = SR_LoadDialog(SR_DLOG_ID, rendererPrivate);
-
- if (dialog != NULL) {
- do {
- ModalDialog(SRgModalFilterUPP, &itemHit);
- HandleHit(
- dialog, itemHit, &done, renderer, canceled, rendererPrivate);
- } while (done == kQ3False);
-
- DisposeDialog(dialog);
- } else {
- Q3XMacintoshError_Post(ResError());
- status = kQ3Failure;
- }
-
- return (status);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: ModalDialogFilter()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- Boolean ModalDialogFilter(
- DialogPtr dialog,
- EventRecord *event,
- short *itemHit)
- {
- Boolean handled = kQ3False;
- char key;
- long menuItem;
-
- switch (event->what) {
- case keyDown: {
- key = (char) (event->message & charCodeMask);
- if (key == '\r' || key == '\3') {
- *itemHit = SR_DLOG_OK;
- handled = kQ3True;
- SimulateButtonClick(dialog, SR_DLOG_OK);
- } else if (key == '\33' ||
- ((event->modifiers & cmdKey) && key == '.')) {
- *itemHit = SR_DLOG_CANCEL;
- handled = kQ3True;
- SimulateButtonClick(dialog, SR_DLOG_CANCEL);
- } else if (event->modifiers & cmdKey) {
- menuItem = MenuKey(key);
- if (menuItem) {
- HandleMenuClick(menuItem);
- handled = kQ3True;
- }
- }
- break;
- }
- case updateEvt: {
- if ((DialogPtr) (event->message) == dialog) {
- DrawDefaultButtonOutline(dialog, SR_DLOG_OK);
- }
- break;
- }
- }
-
- return (handled);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: DrawDefaultButtonOutline()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- void DrawDefaultButtonOutline(
- DialogPtr dialog,
- short item)
- {
- short iType;
- Rect iRect;
- Handle iHandle;
- GrafPtr oldPort;
- PenState oldPenState;
- short buttonOval;
-
- GetDialogItem(dialog, item, &iType, &iHandle, &iRect);
-
- GetPort(&oldPort);
- SetPort((**((ControlHandle) iHandle)).contrlOwner);
-
- GetPenState(&oldPenState);
- PenNormal();
-
- InsetRect(&iRect, -4, -4);
- FrameRoundRect(&iRect, 16, 16);
- buttonOval = (iRect.bottom - iRect.top) / 2 + 2;
-
- PenSize(3, 3);
-
- FrameRoundRect(&iRect, buttonOval, buttonOval);
-
- SetPenState(&oldPenState);
- SetPort(oldPort);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: SR_MacModalDialog()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status SR_MovableModalDialog(
- TQ3RendererObject renderer,
- TQ3DialogAnchor dialogAnchor,
- TQ3Boolean *canceled,
- void *rendererPrivate)
- {
- DialogPtr dialog, whichDlog;
- short itemHit;
- TQ3Boolean done = kQ3False, handled = kQ3False;
- EventRecord event;
-
- dialog = SR_LoadDialog(SR_MOVABLE_DLOG_ID, rendererPrivate);
-
- if (dialog == NULL) {
- Q3XMacintoshError_Post(ResError());
- return (kQ3Failure);
- }
-
- do {
- /*
- * If your dialog handles DiskEvents then include it in the EventMask
- * The extra test (event.what == nullEvent) is so we can pass on null
- * events to the app so it can do background processing.
- */
- if (WaitNextEvent(everyEvent & ~diskMask, &event, 1, NULL) ||
- (event.what == nullEvent)) {
- if (HandledEvent(
- &event,
- dialog,
- &itemHit,
- &done,
- renderer,
- canceled,
- rendererPrivate) == kQ3False) {
- if (IsDialogEvent(&event)) {
- /*
- * This is kind of wierd. If the event is a nullevent
- * then we want to give the dialog and the app a shot at
- * handling it. Hence the next statement.
- */
- handled = (TQ3Boolean) (event.what != nullEvent);
- if (DialogSelect(&event, &whichDlog, &itemHit) &&
- whichDlog == dialog) {
- HandleHit(
- dialog,
- itemHit,
- &done,
- renderer,
- canceled,
- rendererPrivate);
- }
- }
-
- if (!handled) {
- /*
- * At this point we have checked for all events
- * that we are interested in. Give the app a shot
- * at the event
- *
- * Restore the old Resource file ordering
- */
- UseResFile(SRgOldResFile);
-
- /*
- * The app's event-handler
- */
- (dialogAnchor.clientEventHandler)(&event);
-
- /*
- * Call me paranoid, but just in case the app
- * opens another resource file
- */
- SRgOldResFile = CurResFile();
-
- /*
- * Set it back to ours
- */
- UseResFile(SRgResFile);
- }
- }
- }
- } while (done == kQ3False);
-
- DisposeDialog(dialog);
-
- return (kQ3Success);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: SR_LoadDialog()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- DialogPtr SR_LoadDialog(
- short dlogId,
- void *rendererPrivate)
- {
- short iType, checkBoxVal;
- Rect iRect;
- Handle iHandle;
- DialogPtr dialog;
-
- dialog = GetNewDialog(dlogId, NULL, (WindowPtr) -1);
- GetDialogItem(dialog, SR_DLOG_CHECKBOX, &iType, &iHandle, &iRect);
-
- checkBoxVal = ((TSRPrivate *) rendererPrivate)->dummyConfigData;
- SetControlValue((ControlHandle) iHandle, checkBoxVal);
-
- ShowWindow(dialog);
-
- return (dialog);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: HandledEvent()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Boolean HandledEvent(
- EventRecord *event,
- DialogPtr dialog,
- short *itemHit,
- TQ3Boolean *done,
- TQ3RendererObject renderer,
- TQ3Boolean *canceled,
- void *rendererPrivate)
- {
- short part;
- WindowPtr whichWindow;
- TQ3Boolean handled = kQ3False;
- char key;
- long menuItem;
-
- switch (event->what) {
- case mouseDown:
- part = FindWindow(event->where, &whichWindow);
- switch (part) {
- case inDrag: {
- handled = kQ3True;
- if (whichWindow == dialog) {
- DragWindow(
- dialog,
- event->where,
- &((*GetGrayRgn())->rgnBBox));
- } else {
- SysBeep(30);
- }
- break;
- }
- case inContent:
- case inGrow:
- case inGoAway:
- case inZoomIn:
- case inZoomOut: {
- if (whichWindow != dialog) {
- handled = kQ3True;
- SysBeep(30);
- }
- break;
- }
- case inMenuBar: {
- handled = kQ3True;
- menuItem = MenuSelect(event->where);
- HandleMenuClick(menuItem);
- break;
- }
- }
- break;
- case keyDown: {
- key = (char) (event->message & charCodeMask);
- if (key == '\r' || key == '\3') {
- *itemHit = SR_DLOG_OK;
- handled = kQ3True;
- SimulateButtonClick(dialog, SR_DLOG_OK);
- HandleHit(
- dialog, *itemHit, done, renderer, canceled, rendererPrivate);
- } else if (key == '\33' ||
- ((event->modifiers & cmdKey) && key == '.')) {
- *itemHit = SR_DLOG_CANCEL;
- handled = kQ3True;
- SimulateButtonClick(dialog, SR_DLOG_CANCEL);
- HandleHit(
- dialog, *itemHit, done, renderer, canceled, rendererPrivate);
- } else if (event->modifiers & cmdKey) {
- menuItem = MenuKey(key);
- if (menuItem) {
- HandleMenuClick(menuItem);
- handled = kQ3True;
- }
- }
- break;
- }
- case updateEvt: {
- if ((DialogPtr) (event->message) == dialog) {
- DrawDefaultButtonOutline(dialog, SR_DLOG_OK);
- }
- break;
- }
- }
-
- return (handled);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: HandleMenuClick()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- void HandleMenuClick(
- long menuItem)
- {
- short item = LoWord(menuItem);
- short menu = HiWord(menuItem);
- MenuHandle menuH;
- Str255 itemText;
-
- if (menuItem) {
- menuH = GetMenuHandle(menu);
- GetMenuItemText(menuH, item, itemText);
-
- /*
- * This is ugly.
- * We compare names of the menus because we don't know what the
- * application's Menu IDs are. I am using constant strings this will
- * not work on non English systems. You should proabably load some
- * STR resources and compare against them so that the Renderer can be
- * localized.
- */
- if (strncmp((char *) (**menuH).menuData, (char *) "\pEdit", 5) == 0) {
- if (strncmp((char *) itemText, (char *) "\pUndo", 5) == 0) {
- /*
- * Handle Undo if supported
- */
- } else if (strncmp((char *) itemText, (char *) "\pCut", 4) == 0) {
- /*
- * Handle Cut if supported - use DialogCut
- */
- } else if (strncmp((char *) itemText, (char *) "\pCopy", 5) == 0) {
- /*
- * Handle Copy if supported - use DialogCopy
- */
- } else if (strncmp((char *) itemText, (char *) "\pPaste", 6) == 0) {
- /*
- * Handle Paste if supported - use DialogPaste
- */
- } else if (strncmp((char *) itemText, (char *) "\pClear", 6) == 0) {
- /*
- * Handle Clear if supported
- */
- } else {
- /*
- * Nothing else should be selectable in the Edit Menu
- * The calling application should have disabled all others
- * SysBeep or Alert to notify user of error
- */
- SysBeep(30);
- }
- } else if (strncmp(
- (char *) (**menuH).menuData,
- (char *) "\x01\x14", 2) == 0) {
- /*
- * Apple menu was selected. All application specific items
- * in the Apple Menu such as "About..." should have been
- * disabled by the app
- */
- OpenDeskAcc(itemText);
- } else {
- /*
- * No other menu should be selectable
- * The calling application should have disabled all others
- * SysBeep or Alert to notify user of error
- */
- SysBeep(30);
- }
- HiliteMenu(0);
- }
- }
-
-
- /*===========================================================================*\
- *
- * Routine: HandleHit()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status HandleHit(
- DialogPtr dialog,
- short itemHit,
- TQ3Boolean *done,
- TQ3RendererObject renderer,
- TQ3Boolean *canceled,
- void *rendererPrivate)
- {
- short iType, checkBoxVal;
- Rect iRect;
- Handle iHandle;
-
- UNUSED(renderer);
-
- switch (itemHit) {
- case SR_DLOG_OK:
- GetDialogItem(dialog, SR_DLOG_CHECKBOX, &iType, &iHandle, &iRect);
- ((TSRPrivate *) rendererPrivate)->dummyConfigData =
- GetControlValue((ControlHandle) iHandle);
- *done = kQ3True;
- *canceled = kQ3False;
- break;
- case SR_DLOG_CANCEL:
- *done = kQ3True;
- *canceled = kQ3True;
- break;
- case SR_DLOG_CHECKBOX:
- GetDialogItem(dialog, SR_DLOG_CHECKBOX, &iType, &iHandle, &iRect);
- checkBoxVal = GetControlValue((ControlHandle) iHandle);
- SetControlValue((ControlHandle) iHandle, !checkBoxVal);
- break;
- }
-
- return (kQ3Success);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: SimulateButtonClick()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- void SimulateButtonClick(
- DialogPtr dialog,
- short item)
- {
- short iType;
- Rect iRect;
- Handle iHandle;
- long ticks;
-
- GetDialogItem(dialog, item, &iType, &iHandle, &iRect);
- HiliteControl((ControlHandle) iHandle, kControlButtonPart);
- ticks = TickCount() + 8;
-
- while (TickCount() < ticks) {
- /*
- * Spin...
- */
- }
- HiliteControl((ControlHandle) iHandle, 0);
- }
-
- #endif /* WINDOW_SYSTEM_MACINTOSH */
-